/*
 * @Author: zhangyang
 * @Date: 2022-03-01 14:01:31
 * @LastEditTime: 2022-06-23 17:36:31
 * @Description: 网络请求
 */
import axios from 'axios';
import type { Method } from 'axios';
import type { Obj, ResponseObj, UserModule } from '@/typings';
import { CSRF_TOKEN, getToken, removeToken, useLoadingStore } from '@/stores';
import { getCsrf } from '@/api/base';
import { disableCsrf, enableCasdoor } from '@/conf';

/**
 * 创建 Axios 实例
 */
const net = axios.create({
  baseURL: import.meta.env.VITE_BASE_HTTP,
  timeout: -1
});

enum Status {
  TOKEN_NO_USE = 401,
  OK = 201
};

type ApiPath = {
  prefix: string;
  path: string;
};

/**
 * 不需要 token 的请求，默认 post 请求
 */
export const requestWithoutToken = async (
  pathObj: ApiPath,
  param: Obj = {},
  method: Method = 'post'
) => {
  if (!disableCsrf && method !== 'GET') {
    if (!CSRF_TOKEN.value) {
      const { csrf } = await getCsrf();
      CSRF_TOKEN.value = csrf;
    }
    param['_csrf'] = CSRF_TOKEN.value;
  }
  const res = new URLSearchParams(param).toString();
  return net({
    url: `${pathObj.prefix}${pathObj.path}${method === 'get' ? `?${res}` : '' }`,
    method,
    data: JSON.stringify(param),
    headers: {
      'Content-type': 'application/json'
    }
  }) as unknown as Promise<any>;
};
/**
 * 需要 token 的普通请求
 */
export const basicRequest = async (
  pathObj: ApiPath,
  param: Obj = {},
  method: Method = 'post'
) => {
  const token = getToken();
  if (!disableCsrf) {
    if (!CSRF_TOKEN.value) {
      const { csrf } = await getCsrf();
      CSRF_TOKEN.value = csrf;
    }
    param['_csrf'] = CSRF_TOKEN.value;
  }
  const res = new URLSearchParams(param).toString();
  return net({
    url: `${pathObj.prefix}${pathObj.path}${method === 'get' ? `?${res}` : '' }`,
    method,
    data: JSON.stringify(param),
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-type': 'application/json'
    }
  }) as unknown as Promise<any>;
};
export const install: UserModule = (ctx) => {
  const { httpPending } = storeToRefs(useLoadingStore());
  /**
   * 设置请求拦截器
   */
  net.interceptors.request.use((req) => {
    httpPending.value = true;
    return req;
  }, (error) => {
    console.error(error);
    window.$message.error(error);
    return Promise.reject(error);
  });

  /**
   * 设置响应拦截器
   */
  net.interceptors.response.use(async (response) => {
    httpPending.value = false;
    const res = response.data as ResponseObj;
    if (res.code === Status.OK) {
      return res.data;
    } else if (res.code === Status.TOKEN_NO_USE) {
      // 登录过期
      removeToken();
      CSRF_TOKEN.value = '';
      if (enableCasdoor) {
        location.search = '';
      } else {
        await new Promise((resolve) => {
          window.$alert.error({
            title: '提示',
            content: '登录信息过期，请重新登录！',
            'positive-text': '确认',
            closable: false,
            'mask-closable': false,
            'onPositiveClick': () => resolve(true)
          });
        });
        location.href = '/base/login';
      }
    } else {
      const error = res.msg;
      window.$message.error(error);
      throw new Error(error);
    }
  }, (error: Error) => {
    httpPending.value = false;
    console.error(error);
    window.$message.error(error.message);
    throw new Error(error.message);
  });
};